/**
  ******************************************************************************
  * @file    mt006_uart.c
  * @author  MIC Software Team 
  * @version V1.0.0
  * @date    09/01/2020
  * @brief   This file provides all the UART firmware functions.
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, MIC SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT MIC</center></h2>
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "mt006_uart.h"
#include "mt006_rcc.h"

/** @addtogroup MT006_StdPeriph_Driver
  * @{
  */

/** @defgroup UART 
  * @brief UART driver modules
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup UART_Private_Defines
  * @{
  */


/**
  * @}
  */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/** @defgroup UART_Private_Functions
  * @{
  */

/**
  * @brief  Deinitializes the UART peripheral registers to their default reset values.
  * @param  None
  * @retval None
  */
void UART_DeInit(void)
{
    RCC_APBPeriphResetCmd(RCC_PRESETCTRL_UART0, ENABLE);
    RCC_APBPeriphResetCmd(RCC_PRESETCTRL_UART0, DISABLE);
}

/**
  * @brief  Initializes the UART peripheral according to the specified
  *   parameters in the UART_InitStruct .
  * @param  UART_InitStruct: pointer to a UART_InitTypeDef structure
  *   that contains the configuration information for the specified UART peripheral.
  * @retval None
  */
void UART_Init(UART_InitTypeDef* UART_InitStruct)
{
	uint32_t UART_Freq, Baud_div;
    
	/* Check the parameters */
	assert_param(IS_UART_BAUDRATE(UART_InitStruct->UART_BaudRate));  
	assert_param(IS_UART_SEND_BREAK(UART_InitStruct->UART_SendBreak));  
	assert_param(IS_UART_WORD_LENGTH(UART_InitStruct->UART_WordLength));
	assert_param(IS_UART_STOPBITS(UART_InitStruct->UART_StopBits));
	assert_param(IS_UART_PARITY(UART_InitStruct->UART_Parity));
	assert_param(IS_UART_MODE(UART_InitStruct->UART_Mode));
	assert_param(IS_UART_FEN(UART_InitStruct->UART_FEN));

/*---------------------------- UART LINECTRL Configuration -----------------------*/
    UART_Freq = RCC_GetClocksFreq(RCC_CLOCKFREQ_UART0CLK);

	Baud_div = (UART_Freq * 4 + (UART_InitStruct->UART_BaudRate >> 1)) / (UART_InitStruct->UART_BaudRate);
    UART0->IBRD = (Baud_div & 0x3fffc0) >> 6;
    UART0->FBRD = (Baud_div & 0x3f);

    UART0->LCRH = UART_InitStruct->UART_Parity | UART_InitStruct->UART_WordLength | \
                UART_InitStruct->UART_FEN | UART_InitStruct->UART_StopBits | UART_InitStruct->UART_SendBreak;

    UART0->CR = UART_InitStruct->UART_Mode;
}

/**
  * @brief  Fills each UART_InitStruct member with its default value.
  * @param  UART_InitStruct: pointer to a UART_InitTypeDef structure
  *   which will be initialized.
  * @retval None
  */
void UART_StructInit(UART_InitTypeDef* UART_InitStruct)
{
	/* UART_InitStruct members default value */
    UART_InitStruct->UART_SendBreak = UART_SendBreak_Disable;
	UART_InitStruct->UART_FEN = UART_FEN_Enable;
	//UART_InitStruct->UART_BaudRate = 115200;
	//UART_InitStruct->UART_BaudRate = 256000;
	//UART_InitStruct->UART_BaudRate = 1000000;
	UART_InitStruct->UART_BaudRate = 921600;
	UART_InitStruct->UART_WordLength = UART_WordLength_8b;
	UART_InitStruct->UART_StopBits = UART_StopBits_1;
	UART_InitStruct->UART_Parity = UART_Parity_No ;
	//UART_InitStruct->UART_Mode = UART_Mode_Tx | UART_Mode_Rx;
	UART_InitStruct->UART_Mode = UART_Mode_Tx;
}

/**
  * @brief  Enables or disables the specified UART peripheral.
  * @param  NewState: new state of the UART0 peripheral.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void UART_Cmd(FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	
	if (NewState != DISABLE)
	{
		UART0->CR |= UART_CR_UARTEN;
	}
	else
	{
		UART0->CR &= ~UART_CR_UARTEN;
	}
}

/**
  * @brief  Configure the FIFO level at which the TXINTR and RXINTR are triggered.
  * @param  UART_TXFL: TX FIFO level. 
  *   This parameter can be one of the following values:
  *     @arg UART_TXIFLSEL_2
  *     @arg UART_TXIFLSEL_4
  *     @arg UART_TXIFLSEL_8
  *     @arg UART_TXIFLSEL_12
  *     @arg UART_TXIFLSEL_14
  * @param  UART_RXFL: RX FIFO level.
  *   This parameter can be one of the following values:
  *     @arg UART_RXIFLSEL_2
  *     @arg UART_RXIFLSEL_4
  *     @arg UART_RXIFLSEL_8
  *     @arg UART_RXIFLSEL_12
  *     @arg UART_RXIFLSEL_14
  * @retval None
  */
void UART_FIFOLevelConfig(uint32_t UART_TXFL, uint32_t UART_RXFL)
{
	/* Check the parameters */
	assert_param(IS_UART_TXIFLSEL(UART_TXFL));
	assert_param(IS_UART_RXIFLSEL(UART_RXFL));
	
    UART0->IFLS = UART_TXFL | UART_RXFL;
}

/**
  * @brief  Transmits single data through the UART0 peripheral.
  * @param  Data: the data to transmit.
  * @retval None
  */
void UART_SendData(uint8_t Data)
{
	/* Transmit Data */
	UART0->DR = Data;
}

/**
  * @brief  Returns the most recent received data by the UART0 peripheral.
  * @param  None
  * @retval The received data.
  */
uint8_t UART_ReceiveData(void)
{
	/* Receive Data */
	return (UART0->DR & 0xFF);
}

/**
  * @brief  Enables or disables inverse UART Rx Polar .
  * @param  NewState: new state of the UART Rx Polar. 
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void UART_RxPolarInvCmd(FunctionalState NewState)
{
	/* Check parameters */
	assert_param(IS_FUNCTIONAL_STATE(NewState));

	if (NewState != DISABLE)
	{
        RCC->ANACTRL1 |= RCC_ANACTRL1_UART_INVR;
	}
	else
	{
        RCC->ANACTRL1 &= ~RCC_ANACTRL1_UART_INVR;
	}
}

/**
  * @brief  Enables or disables inverse UART Tx Polar .
  * @param  NewState: new state of the UART Tx Polar. 
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void UART_TxPolarInvCmd(FunctionalState NewState)
{
	/* Check parameters */
	assert_param(IS_FUNCTIONAL_STATE(NewState));

	if (NewState != DISABLE)
	{
        RCC->ANACTRL1 |= RCC_ANACTRL1_UART_INVT;
	}
	else
	{
        RCC->ANACTRL1 &= ~RCC_ANACTRL1_UART_INVT;
	}
}

/**
  * @brief  Checks whether the specified UART flag is set or not.
  * @param  UART_FLAG: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg UART_FLAG_RXFE:  Receive FIFO Empty Flag.
  *     @arg UART_FLAG_TXFF:  Transmit FIFO Full Flag.
  *     @arg UART_FLAG_RXFF:  Receive FIFO Full Flag.
  *     @arg UART_FLAG_TXFE:  Transmit FIFO Empty Flag.
  *     @arg UART_FLAG_CTS:   Clear To Send Flag.
  *     @arg UART_FLAG_BUSY:  UART Busy Flag.
  * @retval The new state of UART_FLAG (SET or RESET).
  */
FlagStatus UART_GetFlagStatus(uint32_t UART_FLAG)
{
	FlagStatus bitstatus = RESET;
    
    /* Check the parameters */
	assert_param(IS_UART_FLAG(UART_FLAG));
    
	if ((UART0->TFR & UART_FLAG) != RESET)
	{
		bitstatus = SET;
	}
	else
	{
		bitstatus = RESET;
	}
    
	return bitstatus;
}

/**
  * @brief  Checks whether the specified UART flag is set or not.
  * @param  UART_Error: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg UART_ERROR_FE:  Framing Error Flag.
  *     @arg UART_ERROR_PE:  Parity Error Flag.
  *     @arg UART_ERROR_BE:  Break Error Flag.
  *     @arg UART_ERROR_OE:  Overrun Error Flag.
  * @retval The new state of UART_Error (SET or RESET).
  */
FlagStatus UART_GetErrorStatus(uint32_t UART_Error)
{
	FlagStatus bitstatus = RESET;
    
    /* Check the parameters */
	assert_param(IS_UART_ERROR(UART_Error));
    
	if ((UART0->UART04.RSR & UART_Error) != RESET)
	{
		bitstatus = SET;
	}
	else
	{
		bitstatus = RESET;
	}
    
	return bitstatus;
}

/**
  * @brief  Clear the specified UART error flag.
  * @param  UART_Error: specifies the flag to check.
  *   This parameter can be one of the following values:
  *     @arg UART_ERROR_FE:  Framing Error Flag.
  *     @arg UART_ERROR_PE:  Parity Error Flag.
  *     @arg UART_ERROR_BE:  Break Error Flag.
  *     @arg UART_ERROR_OE:  Overrun Error Flag.
  * @retval The new state of UART_Error (SET or RESET).
  */
void UART_ClearErrorStatusBit(uint32_t UART_Error)
{
    /* Check the parameters */
	assert_param(IS_UART_ERROR(UART_Error));

    UART0->UART04.ECR |= UART_Error;
}

/**
  * @brief  Enables or disables the specified UART interrupts.
  * @param  UART_IT: specifies the UART interrupt sources to be enabled or disabled.
  *   This parameter can be any combination of the following values:
  *     @arg UART_IT_RXIM
  *     @arg UART_IT_TXIM
  *     @arg UART_IT_RTIM
  *     @arg UART_IT_FEIM
  *     @arg UART_IT_PEIM
  *     @arg UART_IT_BEIM
  *     @arg UART_IT_OEIM
  * @param  NewState: new state of the specified UART0 interrupts.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void UART_ITConfig(uint32_t UART_IT, FunctionalState NewState)
{
	/* Check the parameters */
	assert_param(IS_UART_CONFIG_IT(UART_IT));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	
	if (NewState != DISABLE)
	{
        UART0->IMSC |= UART_IT;
	}
	else
	{
        UART0->IMSC &= ~UART_IT;
	}
}

/**
  * @brief  Checks whether the specified UART interrupt has occurred or not.
  * @param  UART_IT: specifies the UART interrupt source to check.
  *   This parameter can be one of the following values:
  *     @arg UART_IT_RXMIS
  *     @arg UART_IT_TXMIS
  *     @arg UART_IT_RTMIS
  *     @arg UART_IT_FEMIS
  *     @arg UART_IT_PEMIS
  *     @arg UART_IT_BEMIS
  *     @arg UART_IT_OEMIS
  * @retval The new state of UART_IT (SET or RESET).
  */
ITStatus UART_GetITStatus(uint32_t UART_IT)
{
	ITStatus bitstatus = RESET;
    
    /* Check the parameters */
	assert_param(IS_UART_GET_IT(UART_IT));

    if((UART0->MIS & UART_IT) != RESET)
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }
	
	return bitstatus;  
}

/**
  * @brief  Clears the UART0 interrupt pending bits.
  * @param  UART_IT: specifies the interrupt pending bit to clear.
  *   This parameter can be any combination of the following values:
  *     @arg UART_IT_RXMIS
  *     @arg UART_IT_TXMIS
  *     @arg UART_IT_RTMIS
  *     @arg UART_IT_FEMIS
  *     @arg UART_IT_PEMIS
  *     @arg UART_IT_BEMIS
  *     @arg UART_IT_OEMIS
  * @retval None
  */
void UART_ClearITPendingBit(uint32_t UART_IT)
{
    /* Check the parameters */
	assert_param(IS_UART_CLEAR_IT(UART_IT));

    UART0->ICR |= UART_IT;
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/******************* (C) COPYRIGHT MIC *****END OF FILE****/

